package blyth;

import java.awt.Point;

public class HealTask extends Task {

    // Note: "goal" should be refreshed based on position
    public Agent target;

    public HealTask(World world, Agent target) {
        super(world, 6, (Point)target.position.clone());
        this.target = target;
    }

    @Override
    public boolean IsValid() {
        // The targeted agent recovered, or blocked
        if (target.energy > World.lowEnergy * 2 || target.isBlocked) {
            return false;
        }
        int teamEnergy = world.TeamEnergy();
        // Don't try to heal if team is poor
        if (teamEnergy <= 50 * World.lowEnergy) {
            return false;
        }        
        // We no longer have sufficent energy to heal
        if (HaveNoEnergyToHeal(assignedTo)) {
            return false;
        }
        return true;
    }

    @Override
    public int AvailabilityFrom(Agent agent) {
        // If agent is low on energy or blocked
        if (HaveNoEnergyToHeal(agent) || agent.isBlocked || agent.goalBlocked) {
            return Distance(agent) + 1000;            
        } else {
            int avgEnergy = (int)Math.round((double)world.TeamEnergy() / (double)world.Friendlies.size());
            // If agent's energy is under avrage
            if (agent.energy < avgEnergy) {
                return Distance(agent) + 60;
            }
        }
        return Distance(agent);
    }

    @Override
    public Command Solve() {
        goal.setLocation(target.position);
        if (assignedTo.position.equals(goal)) {
            int healAmount = (int) Math.round((assignedTo.energy - target.energy) / 2.0);
            return new Command(Command.Action.Transfer, target.id, healAmount);
        }
        return world.Approach(assignedTo, goal);
    }

    public boolean HaveNoEnergyToHeal(Agent agent) {
        return agent.energy < World.lowEnergy * 10;
    }

    public static HealTask MakeNew(World world) {
        // Don't try to heal if team is poor
        if (world.TeamEnergy() > 50 * World.lowEnergy) {
            Agent friendInNeed = null;
            for (int i = 0; i < world.Friendlies.size(); i++) {
                friendInNeed = world.Friendlies.get(i);
                if (friendInNeed.energy < World.lowEnergy && friendInNeed.isBlocked == false) {
                    boolean isHealInTask = false;
                    for (int k = 0; k < world.Friendlies.size(); k++) {
                        for (int j = 0; j < world.Friendlies.get(k).tasks.size(); j++) {
                            Task task = world.Friendlies.get(k).tasks.get(j);
                            if (task.priority == 6 && task.goal.equals(friendInNeed.position)) {
                                isHealInTask = true;
                            }
                        }
                    }
                    if (isHealInTask == false) {
                        return new HealTask(world, friendInNeed);
                    }
                }
            }
        }
        return null;
    }
}